<template>
  <Dialog
    :title="dialogTitle"
    v-model="dialogVisible"
    :max-height="maxHeight"
    :width="width"
    append-to-body
    :before-close="handleClose"
    style="padding-bottom: 0px !important"
  >
    <el-container>
      <el-aside class="aside">
        <el-scrollbar :max-height="maxHeight">
          <div
            class="payment-item"
            :class="{ 'payment-item-active': channel.payStatus }"
            v-for="(channel, index) in state.payMethods.items"
            :key="channel.assetsId"
            @click="selectPayMent(index)"
          >
            <el-image :src="channel.icon" class="icon ml-20px" />
            <el-text class="custom-text-18 ml-10px"> {{ channel.assetsTitle }}</el-text>
            <div class="virtual_san"></div>
            <div class="virtual_dui custom-text-18">✓</div>
          </div>
        </el-scrollbar>
      </el-aside>
      <el-main class="main">
        <div class="payment-info">
          <div class="payment-info-item">
            <div class="custom-text-24 c-[var(--el-color-primary)]!"
              >￥{{ fenToYuan(state.orderInfo.price.totalPrice) }}</div
            >
            <div class="custom-text-18">订单金额</div>
          </div>

          <div class="payment-info-item">
            <div class="custom-text-24 c-[var(--el-color-primary)]!"
              >￥{{ fenToYuan(state.payMethods.totalPayPrice) }}</div
            >
            <div class="custom-text-18">已付金额</div>
          </div>
          <div class="payment-info-item">
            <div class="custom-text-24 c-[var(--el-color-primary)]!"
              >￥{{ fenToYuan(state.orderInfo.price.payPrice) }}</div
            >
            <div class="custom-text-18">待支付金额</div>
          </div>
        </div>

        <div class="mt-20px">
          <el-input
            v-model="nowPayment.payPrice"
            :formatter="(value: any) => verifyNumberIntegerAndFloat(value)"
            class="payment-input custom-text-44"
            ref="inputRef"
          >
            <template #prepend>
              <div class="flex items-center">
                <el-image :src="collection" class="collection-icon" />
                <span class="custom-text-22 ml5"> 收款金额</span>
              </div>
            </template>
          </el-input>
        </div>
        <el-divider border-style="dashed" />
        <div class="max-h-40px" v-if="state.payOrderList.length != 0">
          <el-scrollbar>
            <span class="mt-2px" v-for="item in state.payOrderList" :key="item.id"
              >支付流水:{{ item.no }},支付金额 {{ fenToYuan(item.price) }}元,
              <DictTag class="ml-10px" :type="DICT_TYPE.PAY_ORDER_STATUS" :value="item.status" />
            </span>
          </el-scrollbar>
        </div>

        <div class="mt-20px">
          <DigitKeyboard
            ref="DigitKeyboardRef"
            @on-change="onInputChange"
            @on-confirm="onConfirm"
            :input="nowPayment.payPrice"
          />
        </div>
      </el-main>
    </el-container>
    <template #footer v-if="slots.footer">
      <slot name="footer"></slot>
    </template>
  </Dialog>

  <!-- 展示形式：二维码 URL -->
  <Dialog
    :title="qrCode.title"
    v-model="qrCode.visible"
    width="350px"
    append-to-body
    :close-on-press-escape="false"
    :before-close="handleClosePay"
  >
    <Qrcode :text="qrCode.url" :width="310" />
  </Dialog>

  <!-- 展示形式：BarCode 条形码 -->
  <Dialog
    :title="barCode.title"
    v-model="barCode.visible"
    width="500px"
    append-to-body
    align-center
    :close-on-press-escape="false"
    :before-close="handleClosePay"
  >
    <el-form ref="form" label-width="80px">
      <el-row>
        <el-col :span="24">
          <el-form-item label="条形码" prop="name">
            <el-input
              v-model="barCode.value"
              placeholder="请输入条形码"
              required
              @keydown="handleKeydown"
            />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <div class="flex w-100% justify-end">
            或使用
            <el-link
              type="danger"
              target="_blank"
              href="https://baike.baidu.com/item/条码支付/10711903"
            >
              (扫码枪/扫码盒)
            </el-link>
            扫码
          </div>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <el-button
        type="primary"
        @click="submit0(barCode.channelCode)"
        :disabled="barCode.value.length === 0"
      >
        确认支付
      </el-button>
      <el-button @click="barCode.visible = false">取 消</el-button>
    </template>
  </Dialog>
</template>
<script setup lang="ts">
defineOptions({
  name: 'PayCashierDialog'
})
// 真实支付弹框 todo: 暂时不用
import { defineAsyncComponent, ref, useSlots, watch } from 'vue'
import { DICT_TYPE } from '@/utils/dict'
import { propTypes } from '@/utils/propTypes'
const props = defineProps({
  orderInfo: propTypes.object, //订单信息
  paymentMap: propTypes.array,
  no: propTypes.string
})
import collection from '@/assets/svgs/collection.svg'
import * as PayOrderApi from '@/api/shop/trade/pay'
import * as OrderApi from '@/api/shop/trade/order'
/** 门店会员信息 */
import { useShopUserStoreWithOut } from '@/store/modules/shop/user'
const shopUserStore = useShopUserStoreWithOut()

import { fenToYuan, yuanToFen } from '@/utils'
const DigitKeyboard = defineAsyncComponent(() => import('./digitKeyBoard.vue'))
const slots = useSlots()
// 检测支付环境
const state = reactive({
  orderType: 'goods', // 订单类型; goods - 商品订单, recharge - 充值订单
  orderInfo: computed(() => {
    return props.orderInfo
  }), // 支付单信息 as any, // 支付单信息
  payStatus: 0, // 0=检测支付环境, -2=未查询到支付单信息， -1=支付已过期， 1=待支付，2=订单已支付
  payMethods: computed(() => {
    return props.paymentMap.find((ele: any) => {
      return ele.classify == nowPaymenthds.value.classify
    })
  }) as any, // 可选的支付方式
  payment: '', // 选中的支付方式
  payPrice: 0, //应付金额
  paidPrice: 0, //已付金额
  unpaidPrice: 0, //待支付金额
  payOrderList: [] as any //当前支付方式的支付流水号
})

const DigitKeyboardRef = ref()
const onInputChange = (input: any) => {
  nowPayment.value.payPrice = input
} //输入发生变化时
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('选择支付方式') // 弹窗的标题
const width = ref('715px') //宽度
const maxHeight = ref('545px')
// 选择支付方式
const nowPayment = ref<any>({})
const nowPaymentIndex = ref<any>() //当前支付方式的下标
const inputRef = ref()
const selectPayMent = async (index: any) => {
  nowPaymentIndex.value = index
  let item = state.payMethods.items[nowPaymentIndex.value]
  item.payStatus = !item.payStatus

  // if (interval.value) {
  //   // 如果当前支付没有成功   请先完成当前的操作
  //   message.error('当前支付状态未成功')
  //   return
  // }
  if (item.payStatus) {
  } else {
    item.payStatus = true
  }
  nowPayment.value = item
  nowPayment.value.payPrice = ''
}

/** 打开弹窗 */
const nowPaymenthds = ref() //当前使用的资产

const open = async (payMethods: any) => {
  dialogVisible.value = true
  nowPaymenthds.value = payMethods
  await setNowPayment()
}
const setNowPayment = () => {
  let selectPayMentIndexs = [] as any
  state.payMethods.items.forEach((element, index) => {
    if (element.payStatus) {
      selectPayMentIndexs.push(index)
    }
  })
  if (selectPayMentIndexs.length == 0) {
    nowPayment.value = {}
    selectPayMent(0)
  } else {
    nowPaymentIndex.value = selectPayMentIndexs[0]
    nowPayment.value = state.payMethods.items[nowPaymentIndex.value]
    nowPayment.value.usePayBalance = fenToYuan(nowPayment.value.paybalance)
  }
  console.log(nowPayment.value)
} //设置当前选中的支付方式

/** 提交支付 */
const submitLoading = ref(false) // 提交支付的 loading
const qrCode = ref({
  // 展示形式：二维码
  url: '',
  title: '',
  visible: false
})
const barCode = ref({
  // 展示形式：条形码
  channelCode: '',
  value: '',
  title: '',
  visible: false
})
const submit = (channelCode) => {
  // 条形码支付，需要特殊处理
  if (nowPayment.value.displayMode === PayDisplayModeEnum.BAR_CODE.mode) {
    displayBarCode(channelCode)
    return
  }

  // 微信公众号、小程序支付，无法在 PC 网页中进行
  if (channelCode === PayChannelEnum.WX_PUB.code) {
    message.error('微信公众号支付：不支持 PC 网站')
    return
  }
  if (channelCode === PayChannelEnum.WX_LITE.code) {
    message.error('微信小程序：不支持 PC 网站')
    return
  }

  // 默认的提交处理
  submit0(channelCode)
}
const submit0 = async (channelCode) => {
  submitLoading.value = true
  try {
    const formData = {
      no: props.no,
      userId: shopUserStore.getUser.id,
      pay: {
        classify: nowPaymenthds.value.classify,
        // payStatus: nowPayment.value.payStatus,
        assetsId: nowPayment.value.assetsId,
        paybalance: yuanToFen(nowPayment.value.payPrice)
      },
      ...buildSubmitParam()
    }
    const data = await OrderApi.beforeSubmit(formData)
    // 直接返回已支付的情况，例如说扫码支付
    if (data.status === PayOrderStatusEnum.SUCCESS.status) {
      clearQueryInterval()
      message.success('支付成功！')
      // getAppChannelPayOrderList()
      return
    }

    // 展示对应的界面
    if (data.displayMode === PayDisplayModeEnum.URL.mode) {
      displayUrl(channelCode, data)
    } else if (data.displayMode === PayDisplayModeEnum.QR_CODE.mode) {
      displayQrCode(channelCode, data)
    } else if (data.displayMode === PayDisplayModeEnum.APP.mode) {
      displayApp(channelCode)
    }

    nowPayment.value.payOrderId = data.id //当前支付的支付单号
    // 打开轮询任务
    createQueryInterval()
  } finally {
    submitLoading.value = false
  }
}
/** 构建提交支付的额外参数 */
const buildSubmitParam = () => {
  if (nowPayment.value.displayMode === PayDisplayModeEnum.BAR_CODE.mode) {
    return {
      channelExtras: {
        authCode: barCode.value.value
      }
    }
  }

  return {}
}
/** 提交支付前（条形码支付） */
const displayBarCode = (channelCode) => {
  barCode.value = {
    channelCode: channelCode,
    value: '',
    title: '条码支付',
    visible: true
  }
}
/** 提交支付后，URL 的展示形式 */
const displayUrl = (_channelCode, data) => {
  location.href = data.displayContent
  submitLoading.value = false
}

/** 提交支付后（扫码支付） */
const displayQrCode = (channelCode, data) => {
  let title = '请使用手机浏览器“扫一扫”'
  if (channelCode === PayChannelEnum.ALIPAY_WAP.code) {
    // 考虑到 WAP 测试，所以引导手机浏览器搞
  } else if (channelCode.indexOf('alipay_') === 0) {
    title = '请使用支付宝“扫一扫”扫码支付'
  } else if (channelCode.indexOf('wx_') === 0) {
    title = '请使用微信“扫一扫”扫码支付'
  }
  qrCode.value = {
    title: title,
    url: data.displayContent,
    visible: true
  }
  submitLoading.value = false
}

/** 提交支付后（App） */
const displayApp = (channelCode) => {
  if (channelCode === PayChannelEnum.ALIPAY_APP.code) {
    message.error('支付宝 App 支付：无法在网页支付！')
  }
  if (channelCode === PayChannelEnum.WX_APP.code) {
    message.error('微信 App 支付：无法在网页支付！')
  }
  submitLoading.value = false
}
/** 轮询查询任务 */
const interval = ref<any>(undefined) // 定时任务，轮询是否完成支付

const createQueryInterval = () => {
  if (interval.value) {
    return
  }
  interval.value = setInterval(async () => {
    let paramsData = {
      payOrderId: nowPayment.value.payOrderId,
      channelCode: nowPayment.value.assetsId,
      sync: true
    }
    const data = await PayOrderApi.getSinglePayOrder(paramsData)

    // 已支付
    if (data.status === PayOrderStatusEnum.SUCCESS.status) {
      clearQueryInterval()
      message.success('支付成功！')
      // await getAppChannelPayOrderList()
    }
    // 已取消
    if (data.status === PayOrderStatusEnum.CLOSED.status) {
      clearQueryInterval()
      message.error('支付已关闭！')
      // await getAppChannelPayOrderList()
      // goReturnUrl('close')
    }
  }, 1000 * 2)
}
/** 清空查询任务 */
const clearQueryInterval = () => {
  // 清空各种弹窗
  qrCode.value = {
    title: '',
    url: '',
    visible: false
  }
  barCode.value = {
    channelCode: '',
    value: '',
    title: '条码支付',
    visible: false
  }
  // 清空任务
  clearInterval(interval.value)
  interval.value = undefined
  emit('success', true)
  close()
}

const close = async () => {
  dialogVisible.value = false
}
const emit = defineEmits(['handleOperation', 'success'])

const handleClose = async (done: () => void) => {
  ElMessageBox.confirm('是否取消支付?', '提示', {
    confirmButtonText: '确认取消',
    cancelButtonText: '继续支付',
    type: 'warning'
  })
    .then(() => {
      clearQueryInterval()
      done()
    })
    .catch(() => {
      clearQueryInterval()
    })
}
const handleClosePay = async (done: () => void) => {
  if (!interval.value) {
    done()
    return
  }
  ElMessageBox.confirm('当前支付状态未更新,请谨慎操作?', '提示', {
    confirmButtonText: '确认关闭',
    cancelButtonText: '继续等待',
    type: 'warning'
  })
    .then(() => {
      clearQueryInterval()
      done()
    })
    .catch(() => {})
}
defineExpose({ open, close }) // 提供 open 方法，用于打开弹窗

const message = useMessage() // 消息弹窗
import { ElMessageBox } from 'element-plus'
import { verifyNumberIntegerAndFloat } from '@/utils/formatter'
/** 购物车信息 */
import { PayChannelEnum, PayDisplayModeEnum, PayOrderStatusEnum } from '@/utils/constants'

const onConfirm = () => {
  if (!nowPayment.value.payPrice) {
    message.error('支付金额不能为空')
    return
  }
  if (nowPayment.value.payPrice < 0) {
    message.error('支付金额必须大于0')
    return
  }

  submit(nowPayment.value.assetsId)
} //确认当前支付方式

// 监听选择的支付方式改变时 用来处理不同的 状态
watch(
  () => nowPayment.value,
  (newVal, oldVal) => {
    if (JSON.stringify(oldVal) != '{}' && newVal.code != oldVal.code) {
      if (!oldVal.payOrderList || oldVal.payOrderList?.length == 0) {
        // 如果没有确认 并且支付金额为0时 取消选中状态
        oldVal.flag = false
      }
    }
  }
)
const handleKeydown = (event) => {
  // 检查按键是否是回车键（Enter），扫码枪通常会模拟回车键来提交表单
  if (event.key === 'Enter') {
    event.preventDefault() // 阻止回车键的默认行为，即阻止页面刷新
    event.stopPropagation() // 阻止事件冒泡，确保不会触发上层元素的默认行为
  }
}
</script>
<style lang="scss" scoped>
.aside {
  width: 190px;
}

.main {
  margin-left: 20px;
  width: 470px;
}

:deep(.el-main) {
  --el-main-padding: 0px !important;
  width: 470px;
}

// .payment-item {
//   width: 190px;
//   height: 70px;
//   margin-bottom: 20px;
//   background: url('@/assets/imgs/payCashier/paymentBg.png') center no-repeat;
//   background-size: 100% 100%;
//   cursor: pointer;
//   display: flex;
//   align-items: center;

//   .icon {
//     width: 24px;
//     height: 24px;
//   }

//   .virtual_san {
//     display: none;
//   }

//   .virtual_dui {
//     display: none;
//   }

//   &-active {
//     background: url('@/assets/imgs/payCashier/paymentActive.png') center no-repeat;
//     background-size: 100% 100%;
//     position: relative;

//     .virtual_san {
//       display: block;
//       position: absolute;
//       bottom: 0;
//       right: 0;
//       width: 0;
//       height: 0;
//       border-bottom: 35px solid var(--el-color-primary);
//       border-left: 35px solid transparent;
//       border-bottom-right-radius: 5px;
//     }

//     .virtual_dui {
//       display: block;

//       position: absolute;
//       bottom: -2px;
//       right: 5px;
//       color: #fff;
//       font-family: system-ui;
//     }
//   }
// }

// .payment-info {
//   width: 470px;
//   height: 85px;
//   display: flex;
//   flex-direction: row;
//   justify-content: space-between;
//   align-items: center;
//   background-color: var(--app-content-bg-color) !important;
//   border-radius: 5px;

//   &-item {
//     width: 117.5px;
//     text-align: center;
//   }
// }
// .dark .payment-info {
//   width: 470px;

//   height: 85px;
//   display: flex;
//   flex-direction: row;
//   justify-content: space-between;
//   align-items: center;
//   background-color: var(--app-content-bg-color) !important;
//   border-radius: 5px;

//   &-item {
//     width: 117.5px;
//     text-align: center;
//   }
// }

.payment-input {
  width: 470px;

  height: 60px;

  :deep(.el-input-group__prepend) {
    background: var(--el-color-primary);
    color: #fff;
    padding: 0 10px;
    box-shadow: none;
  }

  :deep(.el-input__inner) {
    --el-input-inner-height: 48px;
  }
}

:deep(.el-divider--horizontal) {
  margin: 20px 0 13px 0;
}

.collection-icon {
  width: 24px;
  height: 24px;
}
</style>
